#include "grass_control.h"
#include "iltdrawprim.h"
#include "ilttexinterface.h"
#include "..\clientinterfaces.h"
#include <algorithm>
#include "ltquatbase.h"
grass_control::grass_control(void):
m_loaded(false)
{
}

grass_control::~grass_control(void)
{
	//for (std::map<char*,HTEXTURE>::iterator it=m_tex_htex.begin();
	//	it!=m_tex_htex.end();++it)
	//{
	//	g_pLTCTexInterface->ReleaseTextureHandle(it->second);
	//}
	//m_tex_htex.clear();
	//m_tex_types.clear();
	//for (std::vector<s_grass_unit*>::iterator it=m_grass_coll.begin();
	//	it!=m_grass_coll.end();++it)
	//{
	//	delete (*it);
	//}
	//m_grass_coll.clear();

	//for (std::vector<char*>::iterator it=temptex.begin();it!=temptex.end();++it)
	//{
	//	if (*it)
	//	{
	//		delete *it;
	//		*it=0;
	//	}
	//}
	//for (std::vector<char*>::iterator it=temptex.begin();
	//	it!=temptex.end();++it)
	//{
	//	if (*it)
	//	{
	//		delete[] (*it);
	//		(*it)=0;
	//	}

	//}

}

void grass_control::load_dates()
{
	if (m_loaded)
	{
		return;
	}


  
	//g_pLTCDrawPrim->GetPlantsDate(temptex,tempvec);
	tempvec=g_pLTCDrawPrim->GetPlantsVecs();
	temptex=g_pLTCDrawPrim->GetPlantsTexs();
 

	//init grass coll
	m_grass_coll.reserve(temptex.size()+5);
	m_render_orders.reserve(temptex.size()+5);
	//load texs;
	for (std::vector<char*>::iterator itt=temptex.begin();
		itt!=temptex.end();++itt)
	{
        s_grass_unit temp_unit;
		std::string temp_str=*itt;

		std::vector<std::string>::iterator _result;
		_result=std::find(m_tex_types.begin(),m_tex_types.end(),temp_str);
		if (_result==m_tex_types.end())
		{
			build_tex(temp_str);
		}
		temp_unit.m_tex=m_tex_htex[temp_str];
		m_grass_coll.push_back(temp_unit);
		m_render_orders.push_back(m_grass_coll.size()-1);
	}


	//load vecs
	int tempindex=0;
	for (std::vector<s_grass_unit>::iterator it=m_grass_coll.begin();
		it!=m_grass_coll.end();++it)
	{
		for (int i=0;i<4;++i)
		{
			it->m_poly.verts[i].x=tempvec[tempindex].x;
			it->m_poly.verts[i].y=tempvec[tempindex].y;
			it->m_poly.verts[i].z=tempvec[tempindex].z;
			++tempindex;
		}
		//create roots
		it->m_foot.x=it->m_poly.verts[0].x+(abs(it->m_poly.verts[3].x-it->m_poly.verts[0].x))/2.0f;
		it->m_foot.y=it->m_poly.verts[0].y+(abs(it->m_poly.verts[3].y-it->m_poly.verts[0].y))/2.0f;
		it->m_foot.z=it->m_poly.verts[0].z+(abs(it->m_poly.verts[3].z-it->m_poly.verts[0].z))/2.0f;
		//create sizes
		//(*it)->m_height=abs((*it)->m_poly.verts[1].y-(*it)->m_poly.verts[0].y);
		//(*it)->m_wide=abs((*it)->m_poly.verts[1].x-(*it)->m_poly.verts[2].x);
		LTVector temp_sourse;
		temp_sourse.x=it->m_poly.verts[0].x;temp_sourse.y=it->m_poly.verts[0].y;temp_sourse.z=it->m_poly.verts[0].z;
		LTVector temp_destw;
		temp_destw.x=it->m_poly.verts[3].x;temp_destw.y=it->m_poly.verts[3].y;temp_destw.z=it->m_poly.verts[3].z;
		LTVector temp_desth;
		temp_desth.x=it->m_poly.verts[1].x;temp_desth.y=it->m_poly.verts[1].y;temp_desth.z=it->m_poly.verts[1].z;
		it->m_wide=temp_sourse.Dist(temp_destw);
		it->m_height=temp_sourse.Dist(temp_desth);


	}

	
	m_loaded=true;



}

void grass_control::render()
{

	if (!m_loaded)
	{
		return;
	}
	/*for (std::vector<s_grass_unit*>::iterator it=m_grass_coll.begin();
		it!=m_grass_coll.end();++it)
	{
		g_pLTCDrawPrim->SetTexture((*it)->m_tex);
		g_pLTCDrawPrim->DrawPrim(&((*it)->m_poly));
	}*/
	for (int i=0;i<m_grass_coll.size();++i)
	{
		g_pLTCDrawPrim->SetTexture(m_grass_coll[m_render_orders[i]].m_tex);
		g_pLTCDrawPrim->DrawPrim(&(m_grass_coll[m_render_orders[i]].m_poly));

	}

}

void grass_control::build_tex(std::string tempstr)
{

	std::string oldstr=tempstr;
	HTEXTURE temphtex=0;
	LTRESULT result;

	
	
	std::string::size_type index=0;;
	std::string::size_type old_index=0;
   while (true)
   {
	    index= tempstr.find("/",old_index);
	   if (index!=std::string::npos)
	   {
		   tempstr.insert(index,"/");
		   old_index=index+2;
	   }
	   else
	   {
		   break;
	   }
	   

   }

	result=g_pLTCTexInterface->CreateTextureFromName(temphtex,tempstr.c_str());
	if (result==LT_OK)
	{
		m_tex_types.push_back(oldstr);
		m_tex_htex.insert(std::make_pair(oldstr,temphtex));
	}


}

void grass_control::update( LTVector camerapos,LTRotation camerarot )
{
	if (!m_loaded)
	{
		return;
	}
	//adjust plants rot
	//compute distances
	LTMatrix tempma;

	camerarot.ConvertToMatrix(tempma);
	//grass_math::quat_to_matrix(camerarot.m_Quat,tempma.m);
	tempma.Inverse();
	for (std::vector<s_grass_unit>::iterator it=m_grass_coll.begin();
		it!=m_grass_coll.end();++it)
	{
	    it->setup_trans(tempma);
		it->m_distance=camerapos.Dist(it->m_foot);
	}
	sort();
	


}

bool operator <(s_grass_unit _one,s_grass_unit _two)
{
	if (_one.m_distance>_two.m_distance)
	{
		return true;
	}
	else
		return false;

}

void grass_control::sort()
{
	std::sort(m_grass_coll.begin(),m_grass_coll.end());

}
//LTmatrix
//[4][4]


void s_grass_unit::setup_trans( LTMatrix _mar )
{
	static float tempx,tempz;
   //set-zero
	m_poly.verts[1].z=m_poly.verts[2].z=m_poly.verts[3].z=m_poly.verts[0].z=0.0f;

	m_poly.verts[1].x=m_poly.verts[0].x=-m_wide/2.0f;
	m_poly.verts[2].x=m_poly.verts[3].x=m_wide/2.0f;

	m_poly.verts[1].y=m_poly.verts[2].y=m_height;
	m_poly.verts[3].y=m_poly.verts[0].y=0.0f;

	for (int i=0;i<4;++i)
	{
		//rotate
		tempx=m_poly.verts[i].x*_mar.m[0][0]+m_poly.verts[i].z*_mar.m[2][0];
		tempz=m_poly.verts[i].x*_mar.m[0][2]+m_poly.verts[i].z*_mar.m[2][2];
		m_poly.verts[i].x=tempx;
		m_poly.verts[i].z=tempz;
		//translate
		m_poly.verts[i].x+=m_foot.x;
		m_poly.verts[i].y+=m_foot.y;
		m_poly.verts[i].z+=m_foot.z;
	}
	

}

/*
void grass_math::quat_to_matrix( const float* pQuat,float mat[4][4] )
{

		float s, xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;



		
		//get the values for matrix calcuation.
		
		s = 2.0f / ((pQuat[0] * pQuat[0]) + (pQuat[1] * pQuat[1]) + 
			(pQuat[2] * pQuat[2]) + (pQuat[3] * pQuat[3]));

		xs = pQuat[0] * s;
		ys = pQuat[1] * s;
		zs = pQuat[2] * s;

		wx = pQuat[3] * xs;
		wy = pQuat[3] * ys;
		wz = pQuat[3] * zs;

		xx = pQuat[0] * xs;
		xy = pQuat[0] * ys;
		xz = pQuat[0] * zs;

		yy = pQuat[1] * ys;
		yz = pQuat[1] * zs;

		zz = pQuat[2] * zs;



		
		//Fill in matrix

		
		mat[0][0] = 1.0f - (yy + zz);
		mat[0][1] = xy - wz;
		mat[0][2] = xz + wy;

		mat[1][0] = xy + wz;
		mat[1][1] = 1.0f - (xx + zz);
		mat[1][2] = yz - wx;

		mat[2][0] = xz - wy;
		mat[2][1] = yz + wx;
		mat[2][2] = 1.0f - (xx + yy);

		mat[0][3] = mat[1][3] = mat[2][3] = mat[3][0] = mat[3][1] = mat[3][2] = 0.0f;
		mat[3][3] = 1.0f;
	


}
*/